package madoop.me;


import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;


public class DriveList
{
    static private final String PATTERN = "partitions %s";      // df -l <FILES> | sed 's/ +/\t/g' | cut -f 1
    
    public static Drive[]     drives = null;
    
    
    public static void reset(String... paths) throws FileNotFoundException, IOException, InterruptedException
    {
        /* Call system df command to get partition info.
         * Only existing directories are included in the df command.
         */
        StringBuilder sb = new StringBuilder();
        for (String path : paths) {
            File file = new File(path);
            if (!file.exists() || !file.isDirectory())
                throw new FileNotFoundException(path);
            sb.append(path).append(' ');
            
        }
        String cmd = String.format(PATTERN, sb.toString());
        System.out.println(cmd);
        
        Process process = Runtime.getRuntime().exec(new String[]{"shell/sysinfo",cmd});
        process.waitFor();
        Scanner scan = new Scanner(process.getInputStream());
        scan.useDelimiter("\n");
        //System.out.println(scan.next());
        if (!scan.next().equalsIgnoreCase("Filesystem"))
            throw new FileNotFoundException("Command: "+cmd);
        
        /* Organize paths by device. */
        Set<String>                 partitions = new HashSet<String>();
        Map<String,List<String>>    device2Entries = new HashMap<String,List<String>>();
        
        for (String path : paths) {
            String partition = scan.next();
            if (partitions.contains(partition)) continue;                     // ensure one entry per partition
            String device = toDevice(partition);
            List<String> entries = device2Entries.get(device);
            if (entries == null) {
                entries = new LinkedList<String>();
                device2Entries.put(device, entries);
            }
            entries.add(path);
        }
        scan.close();
        
        if (device2Entries.isEmpty())
            throw new FileNotFoundException("No partition retrieved. Command: " + cmd);
        
        /* Setup Drive objects. */
        drives = new Drive[device2Entries.size()];
        int i = 0;
        for (Map.Entry<String, List<String>> item : device2Entries.entrySet())
            drives[i++] = new Drive(item.getKey(),item.getValue());
    }
    
    
    private static String toDevice(String partition)
    {
        
        int index = partition.length();
        char ch = partition.charAt(--index);
        while (ch >= '0' && ch <= '9')
            ch = partition.charAt(--index);
        return partition.substring(0,index+1);
    }
    
    
    public static String asString()
    {
        StringBuilder sb = new StringBuilder("Drives:");
        for (Drive d : drives)
            sb.append(' ').append(d.name);
        return sb.toString();
    }
}
